package org.iteam.core.shiro;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.shiro.SecurityUtils;
import org.iteam.core.Constant;
import org.iteam.core.Constant.Function;
import org.iteam.core.Constant.Permission;
import org.iteam.core.model.sys.SysFunction;
import org.iteam.core.service.sys.SysFunctionService;
import org.iteam.core.service.sys.SysUserService;
import org.iteam.core.utils.WildcardMatcher;
import org.iteam.core.view.sys.SysPermissionView;

public class AuthUtils {
	private static Map<String, SysFunction> map = new HashMap<String, SysFunction>();
	private static Map<String, SysFunction> map_ = new HashMap<String, SysFunction>();
	private static Map<String, Set<String>> perms = new HashMap<String, Set<String>>();
	private static Map<String, Map<String, SysPermissionView>> perms_ = new HashMap<String, Map<String, SysPermissionView>>();

	static {
		load();
		loadPermissions();
	}

	public static void main(String[] args) {

	}

	public static void load() {
		map_.clear();
		map.clear();
		try {
			List<SysFunction> list = SysFunctionService.getInstance()
					.queryAll();
			Map<String, SysFunction> map = new HashMap<String, SysFunction>();
			for (SysFunction sp : list) {
				if (sp.getAuth() != null && sp.getAuth().indexOf("*") > -1) {
					map_.put(sp.getAuth(), sp);
				}
				map.put(sp.getAuth(), sp);
			}
			AuthUtils.map = map;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static void loadPermissions() {
		perms.clear();
		List<SysPermissionView> list = SysUserService.getInstance()
				.getPermissionsAll();
		for (SysPermissionView spv : list) {
			if (perms.containsKey(spv.getPermission_role())) {
				Set<String> setp = perms.get(spv.getPermission_role());
				setp.add(spv.getAuth());
			} else {
				Set<String> setp = new HashSet<String>();
				setp.add(spv.getAuth());
				perms.put(spv.getPermission_role(), setp);
			}
			if (perms_.containsKey(spv.getPermission_role())) {
				Map<String, SysPermissionView> setp = perms_.get(spv
						.getPermission_role());
				setp.put(spv.getAuth(), spv);
			} else {
				Map<String, SysPermissionView> setp = new HashMap<String, SysPermissionView>();
				setp.put(spv.getAuth(), spv);
				perms_.put(spv.getPermission_role(), setp);
			}
		}
	}

	/**
	 * 根据用户角色获取当前角色的权限
	 * 
	 * @param role
	 * @return
	 */
	public static Set<String> getPermissions(String role) {
		if (perms.containsKey(role)) {
			return perms.get(role);
		}
		return new HashSet<String>();
	}

	public static boolean isPermission(String permission) {
		Set<String> sets = getPermissions(SecurityUtils.getSubject()
				.getSession().getAttribute(Constant.SESSION_CURRENT_ROLE_CODE)
				.toString());

		for (String key : sets) {
			if (WildcardMatcher.match(permission, key, true)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 是否需要验证权限 <br>
	 * -1: 不要验证 <br>
	 * 0:需要验证允许通过 <br>
	 * 1:需要验证禁止通过 <br>
	 * 2:只验证是否登录 <br>
	 * -2:禁止访问
	 * 
	 * @param auth
	 * @return
	 */
	public static int validate(String auth) {
		boolean containsKey = false;
		if (!map.containsKey(auth))
			for (String key : map_.keySet()) {
				if (WildcardMatcher.match(auth, key, true)) {
					auth = key;
					break;
				}
			}
		containsKey = map.containsKey(auth);
		if (containsKey) {
			SysFunction spv = map.get(auth);
			if (Function.Mode.AUTH.ecode.equals(spv.getMode()))
				if (perms_.containsKey(SecurityUtils.getSubject().getSession()
						.getAttribute(Constant.SESSION_CURRENT_ROLE_CODE))) {
					Map<String, SysPermissionView> aa = perms_
							.get(SecurityUtils
									.getSubject()
									.getSession()
									.getAttribute(
											Constant.SESSION_CURRENT_ROLE_CODE));
					if (aa.containsKey(auth)) {
						if (Permission.Mode.PERMIT.ecode.equals(aa.get(auth)
								.getAuth_mode())) {
							return 0;
						} else {
							return 1;
						}
					} else {
						return -2;
					}
				} else {
					return -2;
				}
			else if (Function.Mode.LOGIN.ecode.equals(spv.getMode())) {
				return 2;
			} else if (Function.Mode.NOAUTH.ecode.equals(spv.getMode())) {
				return -1;
			} else {
				return -1;
			}
		} else {
			return -2;
		}
	}

}
